#ifndef _FlashLogBuffManager_H_
#define _FlashLogBuffManager_H_

#include <stdint.h>
#include <stdlib.h>
#include "rtctime.h"
#include "flashtoeep.h"

#ifdef __cplusplus
extern "C"
{
#endif

	typedef struct
	{
		uint32_t flash_base; 
		uint32_t site_next;	 
		uint32_t sits_total; 
		uint16_t sits_per_sector;
		uint16_t sits_per_extpage;
		uint16_t err;	  
		uint16_t checked; 
	} log_buff_info_type;

	typedef struct
	{
		uint16_t (*init)(void);
		uint16_t (*save)(void *dat);
		uint16_t (*read)(uint32_t site, void *buff);
		uint16_t (*alain)(void);
		uint32_t (*site2addr)(uint32_t site);
		uint16_t (*head_search)(uint32_t num, uint32_t *site_des);
		int32_t (*time_search)(sig_time_type time, int8_t mode);
		int32_t (*time_quick_search)(sig_time_type time, int8_t mode); 
	} log_buff_api_type;

	typedef struct
	{
		uint32_t buff_amount;										   
		uint32_t first_base;										   
		uint32_t buff_size;											   
		uint32_t sector_size;										   
		uint32_t ext_page_size;										   
		uint32_t data_size;											   
		log_buff_info_type *info;									   
		void (*erase)(uint32_t addr);								   
		void (*program)(uint32_t addr, uint8_t *p_data, uint16_t Len); 
		void (*read)(uint32_t addr, uint8_t *p_data, uint16_t Len);	   
		void (*full_callback)(uint8_t mode);						   
		const log_buff_api_type *api;								   
	} log_buff_cfg_type;

	uint16_t log_buff_init(const log_buff_cfg_type *cfg);
	uint16_t log_buff_save(const log_buff_cfg_type *cfg, void *dat);
	uint16_t log_buff_read(const log_buff_cfg_type *cfg, uint32_t site, void *buff);
	uint16_t log_buff_align(const log_buff_cfg_type *cfg);
	uint16_t log_buff_head_search(const log_buff_cfg_type *cfg, uint32_t num, uint32_t *site_des); 
	int32_t log_buff_time_search(const log_buff_cfg_type *cfg, sig_time_type time, int8_t mode);   
	uint32_t log_buff_site2addr(const log_buff_cfg_type *cfg, uint32_t site);					   
	
	int32_t log_buff_time_quick_search(const log_buff_cfg_type *cfg, sig_time_type time, int8_t mode);

#define log_buff_api_make(obj)                                          \
	uint16_t obj##_init(void) { return log_buff_init(&obj); }           \
	uint16_t obj##_save(void *dat) { return log_buff_save(&obj, dat); } \
	uint16_t obj##_read(uint32_t site, void *buff)                      \
	{                                                                   \
		return log_buff_read(&obj, site, buff);                         \
	}                                                                   \
	uint16_t obj##_alain(void) { return log_buff_align(&obj); }         \
	uint32_t obj##_site2addr(uint32_t site)                             \
	{                                                                   \
		return log_buff_site2addr(&obj, site);                          \
	}                                                                   \
	uint16_t obj##_head_search(uint32_t num, uint32_t *site_des)        \
	{                                                                   \
		return log_buff_head_search(&obj, num, site_des);               \
	}                                                                   \
	int32_t obj##_time_search(sig_time_type time, int8_t mode)          \
	{                                                                   \
		return log_buff_time_search(&obj, time, mode);                  \
	}                                                                   \
	int32_t obj##_time_quick_search(sig_time_type time, int8_t mode)    \
	{                                                                   \
		return log_buff_time_quick_search(&obj, time, mode);            \
	}                                                                   \
	const log_buff_api_type obj##_api = {                               \
		obj##_init,                                                     \
		obj##_save,                                                     \
		obj##_read,                                                     \
		obj##_alain,                                                    \
		obj##_site2addr,                                                \
		obj##_head_search,                                              \
		obj##_time_search,                                              \
		obj##_time_quick_search}
#define log_buff_api_ref(obj) extern const log_buff_api_type obj##_api
#define log_buff_api_name(obj) &obj##_api

#ifdef __cplusplus
}
#endif

#endif
